package top.lidee.common.service.impl;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.collect.Lists;
import top.lidee.common.dto.AccountInfo;
import top.lidee.common.dto.UserInfo;
import top.lidee.common.enums.StatusEnum;
import top.lidee.common.interceptor.AppletInterceptor;
import top.lidee.common.service.GoodsService;
import top.lidee.common.service.MerchantService;
import top.lidee.common.service.StoreService;
import top.lidee.common.service.twice.applet.MtStoreCateService;
import top.lidee.common.service.twice.management.BmsManagerService;
import top.lidee.common.service.twice.popularize.PtpBeesInfoService;
import top.lidee.common.util.CommonUtil;
import top.lidee.framework.annoation.OperationServiceLog;
import top.lidee.framework.enums.CommonExceptionEnum;
import top.lidee.framework.exception.BusinessCheckException;
import top.lidee.framework.pagination.PaginationRequest;
import top.lidee.framework.pagination.PaginationResponse;
import top.lidee.framework.result.GlobalCheck;
import top.lidee.framework.result.PageUtils;
import top.lidee.framework.result.ResponseResult;
import top.lidee.module.backendApi.twice.page.Query;
import top.lidee.repository.mapper.*;
import top.lidee.repository.model.*;
import top.lidee.repository.model.twice.local.LoginUserLoc;
import top.lidee.repository.model.twice.pojo.applet.MtStoreCateEntity;
import top.lidee.repository.model.twice.pojo.management.BmsManagerEntity;
import top.lidee.repository.model.twice.pojo.popularize.PtpBeesInfoEntity;
import top.lidee.repository.model.twice.vo.applet.*;
import top.lidee.utils.CopyBean;
import top.lidee.utils.MyCollUtil;
import top.lidee.utils.StringUtil;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import lombok.AllArgsConstructor;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.PageRequest;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

import static top.lidee.framework.constant.SystemConstants.ADMIN;
import static top.lidee.framework.constant.SystemConstants.ADMIN_NUMBER;
import static top.lidee.utils.MapParamsUtil.getKey;

/**
 * 商户业务实现类
 * <p>
 * Created by FSQ
 * CopyRight https://www.lidee.top
 */
@Service
@AllArgsConstructor
public class MerchantServiceImpl extends ServiceImpl<MtMerchantMapper, MtMerchant> implements MerchantService {

    private MtMerchantMapper mtMerchantMapper;

    private MtStoreMapper mtStoreMapper;

    private final MtUserMapper mtUserMapper;

    private final MtGoodsMapper mtGoodsMapper;

    private final MtStoreCateService mtStoreCateService;

    private final BmsManagerService bmsManagerService;

    private final PtpBeesInfoService ptpBeesInfoService;



    private static final Logger logger = LoggerFactory.getLogger(MerchantServiceImpl.class);

    /**
     * 分页查询商户列表
     *
     * @param paginationRequest
     * @return
     */
    @Override
    public PaginationResponse<MtMerchant> queryMerchantListByPagination(PaginationRequest paginationRequest, Integer managerId) {
        Page<MtMerchant> pageHelper = PageHelper.startPage(paginationRequest.getCurrentPage(), paginationRequest.getPageSize());
        LambdaQueryWrapper<MtMerchant> lambdaQueryWrapper = Wrappers.lambdaQuery();
        lambdaQueryWrapper.ne(MtMerchant::getStatus, StatusEnum.DISABLE.getKey());

        String name = paginationRequest.getSearchParams().get("name") == null ? "" : paginationRequest.getSearchParams().get("name").toString();
        if (StringUtils.isNotBlank(name)) {
            lambdaQueryWrapper.like(MtMerchant::getName, name);
        }
        String status = paginationRequest.getSearchParams().get("status") == null ? "" : paginationRequest.getSearchParams().get("status").toString();
        if (StringUtils.isNotBlank(status)) {
            lambdaQueryWrapper.eq(MtMerchant::getStatus, status);
        }
        String id = paginationRequest.getSearchParams().get("id") == null ? "" : paginationRequest.getSearchParams().get("id").toString();
        if (StringUtils.isNotBlank(id)) {
            lambdaQueryWrapper.eq(MtMerchant::getId, id);
        }

        //只查询代理商自己新增的或代理商下的小蜜蜂新增的,admin查所有
        if (!Objects.equals(managerId, 1)) {
            BmsManagerEntity manager = bmsManagerService.getById(managerId);
            Optional.ofNullable(manager).ifPresent(po -> {
                List<String> invitationCodes = Lists.newArrayList();

                List<PtpBeesInfoEntity> ptps = ptpBeesInfoService.list(Wrappers.<PtpBeesInfoEntity>lambdaQuery()
                        .eq(PtpBeesInfoEntity::getManagerId, managerId));
                Optional.ofNullable(ptps).ifPresent(item -> {
                    invitationCodes.addAll(item.stream().map(PtpBeesInfoEntity::getInvitationCode).collect(Collectors.toList()));
                });

                invitationCodes.add(po.getInvitationCode());

                lambdaQueryWrapper.in(MtMerchant::getInviterNumber, invitationCodes);
            });
        }


        lambdaQueryWrapper.orderByAsc(MtMerchant::getStatus).orderByDesc(MtMerchant::getId);
        List<MtMerchant> dataList = mtMerchantMapper.selectList(lambdaQueryWrapper);

        PageRequest pageRequest = PageRequest.of(paginationRequest.getCurrentPage(), paginationRequest.getPageSize());
        PageImpl pageImpl = new PageImpl(dataList, pageRequest, pageHelper.getTotal());
        PaginationResponse<MtMerchant> paginationResponse = new PaginationResponse(pageImpl, MtMerchant.class);
        paginationResponse.setTotalPages(pageHelper.getPages());
        paginationResponse.setTotalElements(pageHelper.getTotal());
        paginationResponse.setContent(dataList);

        return paginationResponse;
    }

    /**
     * 保存商户信息
     *
     * @param merchant 商户信息
     * @return
     * @throws BusinessCheckException
     */
    @Override
    @Transactional
    @OperationServiceLog(description = "保存商户信息")
    public MtMerchant saveMerchant(MtMerchant merchant) {
        MtMerchant mtMerchant = new MtMerchant();

        // 编辑商户
        if (merchant.getId() != null) {
            mtMerchant = queryMerchantById(merchant.getId());
        }

        if (merchant.getNo() == null || StringUtil.isEmpty(merchant.getNo())) {
            mtMerchant.setNo(CommonUtil.createMerchantNo());
        } else {
            mtMerchant.setNo(merchant.getNo());
        }
        if (merchant.getType() != null) {
            mtMerchant.setType(merchant.getType());
        }
        mtMerchant.setName(merchant.getName());
        mtMerchant.setLogo(merchant.getLogo());
        mtMerchant.setContact(merchant.getContact());
        mtMerchant.setOperator(merchant.getOperator());
        mtMerchant.setUpdateTime(new Date());
        if (merchant.getId() == null) {
            mtMerchant.setCreateTime(new Date());
        }
        mtMerchant.setWxAppId(merchant.getWxAppId());
        mtMerchant.setWxAppSecret(merchant.getWxAppSecret());
        mtMerchant.setWxOfficialAppId(merchant.getWxOfficialAppId());
        mtMerchant.setWxOfficialAppSecret(merchant.getWxOfficialAppSecret());
        mtMerchant.setDescription(merchant.getDescription());
        mtMerchant.setPhone(merchant.getPhone());
        mtMerchant.setAddress(merchant.getAddress());
        mtMerchant.setStatus(merchant.getStatus());
        mtMerchant.setInviterNumber(merchant.getInviterNumber());
        // mtMerchant.setCateId(merchant.getCateId());

        if (mtMerchant.getStatus() == null) {
            mtMerchant.setStatus(StatusEnum.ENABLED.getKey());
        }
        if (mtMerchant.getId() == null || mtMerchant.getId() < 1) {
            this.save(mtMerchant);
        } else {
            mtMerchantMapper.updateById(mtMerchant);
        }
        return mtMerchant;
    }

    /**
     * 根据ID获取商户信息
     *
     * @param id 商户ID
     * @return
     * @throws BusinessCheckException
     */
    @Override
    public MtMerchant queryMerchantById(Integer id) {
        if (id == null || id < 1) {
            return null;
        }
        return mtMerchantMapper.selectById(id);
    }

    /**
     * 根据名称获取商户信息
     *
     * @param name 商户名称
     * @return
     * @throws BusinessCheckException
     */
    @Override
    public MtMerchant queryMerchantByName(String name) {
        MtMerchant mtMerchant = mtMerchantMapper.queryMerchantByName(name);
        return mtMerchant;
    }

    /**
     * 根据商户号获取商户信息
     *
     * @param merchantNo 商户号
     * @return
     */
    @Override
    public MtMerchant queryMerchantByNo(String merchantNo) {
        return mtMerchantMapper.queryMerchantByNo(merchantNo);
    }

    /**
     * 根据商户号获取商户ID
     *
     * @param merchantNo 商户号
     * @return
     */
    @Override
    public Integer getMerchantId(String merchantNo) {
        if (merchantNo == null || StringUtil.isEmpty(merchantNo)) {
            return 0;
        }
        MtMerchant mtMerchant = queryMerchantByNo(merchantNo);
        if (mtMerchant != null) {
            return mtMerchant.getId();
        } else {
            return 0;
        }
    }

    /**
     * 更新商户状态
     *
     * @param id       商户ID
     * @param operator 操作人
     * @param status   状态
     * @return
     * @throws BusinessCheckException
     */
    @Override
    @Transactional
    @OperationServiceLog(description = "修改商户状态")
    public void updateStatus(Integer id, String operator, String status) throws BusinessCheckException {
        MtMerchant mtMerchant = queryMerchantById(id);
        if (null == mtMerchant) {
            throw new BusinessCheckException("该商户不存在.");
        }

        mtMerchant.setStatus(status);
        mtMerchant.setUpdateTime(new Date());
        mtMerchant.setOperator(operator);

        mtMerchantMapper.updateById(mtMerchant);
    }

    /**
     * 根据条件查询商户列表
     *
     * @param params 查询参数
     * @return
     */
    @Override
    public List<MtMerchant> queryMerchantByParams(Map<String, Object> params) {
        LambdaQueryWrapper<MtMerchant> lambdaQueryWrapper = Wrappers.lambdaQuery();
        lambdaQueryWrapper.ne(MtMerchant::getStatus, StatusEnum.DISABLE.getKey());

        String merchantId = params.get("merchantId") == null ? "" : params.get("merchantId").toString();
        if (StringUtils.isNotBlank(merchantId)) {
            lambdaQueryWrapper.eq(MtMerchant::getId, merchantId);
        }
        String storeId = params.get("storeId") == null ? "" : params.get("storeId").toString();
        if (StringUtils.isNotBlank(storeId) && StringUtil.isEmpty(merchantId)) {
            MtStore mtStore = mtStoreMapper.selectById(storeId);
            if (mtStore != null && mtStore.getMerchantId() > 0) {
                lambdaQueryWrapper.eq(MtMerchant::getId, mtStore.getMerchantId());
            }
        }
        String name = params.get("name") == null ? "" : params.get("name").toString();
        if (StringUtils.isNotBlank(name)) {
            lambdaQueryWrapper.like(MtMerchant::getName, name);
        }
        String status = params.get("status") == null ? "" : params.get("status").toString();
        if (StringUtils.isNotBlank(status)) {
            lambdaQueryWrapper.eq(MtMerchant::getStatus, status);
        }

        lambdaQueryWrapper.orderByAsc(MtMerchant::getStatus).orderByDesc(MtMerchant::getId);
        List<MtMerchant> dataList = mtMerchantMapper.selectList(lambdaQueryWrapper);

        return dataList;
    }


    /**
     * @param vo
     * @return top.lidee.framework.result.ResponseResult
     * @description 成为商户
     * @author zhangyiheng
     * @date 2024/9/24 09:49
     */
    @Override
    @Transactional
    public ResponseResult becomeAMerchant(MtMerchantVo vo, UserInfo userInfo) {
        MtUser mtUser = mtUserMapper.selectById(userInfo.getId());
        Integer merchantId = mtUser.getMerchantId();

        //判断当前用户是否已经是商户
        if (!Objects.equals(merchantId, 0)) {
            return ResponseResult.errorResult(CommonExceptionEnum.NYJZCGL);
        }


        MtMerchant merchant = this.getOne(Wrappers.<MtMerchant>lambdaQuery()
                .eq(MtMerchant::getPhone, vo.getPhone()));
        if (!Objects.isNull(merchant)) {
            return ResponseResult.errorResult(CommonExceptionEnum.SHYCZ);
        }


        MtMerchant mtMerchant = CopyBean.copyBean(vo, MtMerchant.class);
        mtMerchant.setNo(CommonUtil.createMerchantNo());
        mtMerchant.setStatus(StatusEnum.ENABLED.getKey());
        //如果没有填小蜜蜂推广，默认在admin下
        if (Objects.isNull(vo.getInviterNumber())) {
            mtMerchant.setInviterNumber(ADMIN_NUMBER);
        } else {
            mtMerchant.setInviterNumber(vo.getInviterNumber());
        }
        mtMerchant.setOperator("自行注册");
        this.save(mtMerchant);

        //设置user
        mtUser.setMerchantId(mtMerchant.getId());
        mtUserMapper.update(mtUser, Wrappers.<MtUser>lambdaUpdate()
                .eq(MtUser::getId, mtUser.getId()));


        return ResponseResult.ok();
    }

    /**
     * @param params
     * @return top.lidee.framework.result.ResponseResult
     * @description 根据分类id查询商户信息 分页
     * @author zhangyiheng
     * @date 2024/9/25 10:48
     */
    @Override
    public ResponseResult conditionalQueries(Map<String, Object> params) {

        Integer cateId = (Integer) params.get("cateId");

        List<MtStoreCateEntity> cates = mtStoreCateService.list(Wrappers.<MtStoreCateEntity>lambdaQuery()
                .eq(MtStoreCateEntity::getParentId, cateId));

        List<MtStore> stores = mtStoreMapper.selectList(Wrappers.<MtStore>lambdaQuery().in(MtStore::getCateId, cates.stream().map(MtStoreCateEntity::getCategoryId).collect(Collectors.toList())));
        if (MyCollUtil.isNotEmpty(stores)){
            LambdaQueryWrapper<MtMerchant> wrapper = Wrappers.<MtMerchant>lambdaQuery().in(MtMerchant::getId, stores.stream().map(MtStore::getMerchantId).distinct().collect(Collectors.toList()));

            return getResponseResult(params, wrapper);

        }
        return ResponseResult.ok();

    }

    private ResponseResult getResponseResult(Map<String, Object> params, LambdaQueryWrapper<MtMerchant> wrapper) {
        IPage<MtMerchant> page = this.page(
                new Query<MtMerchant>().getPage(params),
                wrapper
        );

        List<MtMerchant> records = page.getRecords();

        List<MtMerchant> res = new ArrayList<>();
        if (MyCollUtil.isNotEmpty(records)) {
            for (MtMerchant record : records) {

                //查詢默认店鋪
                List<MtStore> storeList = mtStoreMapper.selectList(Wrappers.<MtStore>lambdaQuery()
                        .eq(MtStore::getMerchantId, record.getId()));
                if (MyCollUtil.isNotEmpty(storeList)) {
                    //组装返回数据
                    for (MtStore store : storeList) {
                        MtMerchant mtMerchant = CopyBean.copyBean(record, MtMerchant.class);
                        mtMerchant.setName(mtMerchant.getName() + " (" + store.getName() + ")");
                        mtMerchant.setAddress(store.getAddress());

                        res.add(mtMerchant);

                    }
                }
            }

            IPage<MtMerchant> pageVo = new com.baomidou.mybatisplus.extension.plugins.pagination.Page<>();
            pageVo.setTotal(page.getTotal());
            pageVo.setPages(page.getPages());
            pageVo.setCurrent(page.getCurrent());
            pageVo.setRecords(res);
            pageVo.setSize(res.size());
            return ResponseResult.okResultPage("page", new PageUtils(pageVo));
        }


        return ResponseResult.okResultPage("page", new PageUtils(page));
    }

    /**
     * @param params
     * @return top.lidee.framework.result.ResponseResult
     * @description 搜索栏：根据商户标题(名)/地址,模糊搜索分页
     * @author zhangyiheng
     * @date 2024/9/25 11:03
     */
    @Override
    public ResponseResult conditionalLikeQueries(Map<String, Object> params) {

        String key = getKey(params);

        LambdaQueryWrapper<MtMerchant> wrapper = Wrappers.<MtMerchant>lambdaQuery()
                .like(StrUtil.isNotBlank(key), MtMerchant::getName, key);

        List<Integer> list = mtStoreMapper.selectList(Wrappers.<MtStore>lambdaQuery()
                .eq(MtStore::getStatus, StatusEnum.ENABLED.getKey())
                .like(MtStore::getAddress, key)).stream().map(MtStore::getMerchantId).collect(Collectors.toList());

        if (MyCollUtil.isNotEmpty(list)) {
            wrapper.or().in(MtMerchant::getId, list);
        }


        return getResponseResult(params, null);
    }


    /**
     * @param merchantsId
     * @return top.lidee.framework.result.ResponseResult
     * @description 点击商户进入商铺，查询商品
     * @author zhangyiheng
     * @date 2024/9/25 11:19
     */
    @Override
    public ResponseResult getInfoAShopListByMerchantsId(Integer merchantsId) {
        GetInfoAShopListByMerchantsIdVo vo = new GetInfoAShopListByMerchantsIdVo();
        MtMerchant merchant = this.getById(merchantsId);
//        vo.setMerchant(merchant);

        LambdaQueryWrapper<MtStore> wrapper = Wrappers.<MtStore>lambdaQuery()
                .eq(MtStore::getMerchantId, merchant.getId())
                .eq(MtStore::getStatus, StatusEnum.ENABLED.getKey());

        //查询商户下的默认店铺
        wrapper.eq(MtStore::getIsDefault, "Y");
        MtStore store = mtStoreMapper.selectOne(wrapper);
//        vo.setStore(store);

        //查询店铺下商品
        List<MtGoods> list = mtGoodsMapper.selectList(Wrappers.<MtGoods>lambdaQuery()
                .eq(MtGoods::getStoreId, store.getId()));

        vo.setMtGoods(list);

        return ResponseResult.okResult(vo);
    }

    /**
     * @param userInfo
     * @return top.lidee.framework.result.ResponseResult
     * @description 查询当前用户是否是商户
     * @author zhangyiheng
     * @date 2024/9/26 10:11
     */
    @Override
    public ResponseResult isMerchant(UserInfo userInfo) {
        Integer merchantId = mtUserMapper.selectById(userInfo.getId()).getMerchantId();

        //判断当前用户是否已经是商户
        if (!Objects.equals(merchantId, 0)) {
            return ResponseResult.errorResult(CommonExceptionEnum.NYJZCGL);
        }

        return ResponseResult.ok();
    }

    /**
     * @param storeId
     * @return top.lidee.framework.result.ResponseResult
     * @description 在保证是当前商户下 根据店铺id查询店铺
     * @author zhangyiheng
     * @date 2024/9/26 15:49
     */
    @Override
    public ResponseResult getStoreById(Integer storeId, Integer merchantsId) {

        //在保证是当前商户下
        MtStore store = mtStoreMapper.selectById(storeId);

        if (!Objects.equals(store.getMerchantId(), merchantsId)) {
            return ResponseResult.errorResult(CommonExceptionEnum.DQSHXWCDPXX);
        }

        //查询店铺下商品
        List<MtGoods> list = mtGoodsMapper.selectList(Wrappers.<MtGoods>lambdaQuery()
                .eq(MtGoods::getStoreId, store.getId()));

        return ResponseResult.okResult(list);
    }

    //==============ClientMerchantsController start==============

    /**
     * @param userInfo
     * @return top.lidee.framework.result.ResponseResult
     * @description 查询当前用户下的商户以及商户对应店铺和店铺商品信息
     * @author zhangyiheng
     * @date 2024/9/26 16:36
     */
    @Override
    public ResponseResult getCurrentUserCorrespondsMerchantsAll(UserInfo userInfo) {
        //判断当前登录人是否存在商户信息
        MtUser mtUser = mtUserMapper.selectById(userInfo.getId());

        if (Objects.isNull(mtUser.getMerchantId()) || Objects.equals(mtUser.getMerchantId(), 0)) {
            return ResponseResult.errorResult(CommonExceptionEnum.WZCSH);
        }

        CurrentUserCorrespondsMerchantsAllVo vo = new CurrentUserCorrespondsMerchantsAllVo();

        MtMerchant merchant = this.getById(mtUser.getMerchantId());
        vo.setMerchant(merchant);

        List<MtStore> stores = mtStoreMapper.selectList(Wrappers.<MtStore>lambdaQuery()
                .eq(MtStore::getMerchantId, merchant.getId()));

        List<StoreAGoodsVo> storeAGoodsVos = CopyBean.copyBeanList(stores, StoreAGoodsVo.class);

        //查询店铺下商品集合和主要分类名
        if (MyCollUtil.isNotEmpty(storeAGoodsVos)) {
            storeAGoodsVos.forEach(po -> {
                //查询店铺下商品
                List<MtGoods> goods = mtGoodsMapper.selectList(Wrappers.<MtGoods>lambdaQuery()
                        .eq(MtGoods::getStoreId, po.getId()));
                po.setGoods(goods);

                //设置主营分类名
                MtStoreCateEntity cate = mtStoreCateService.getById(po.getCateId());
                if (!Objects.isNull(cate)) {
                    po.setCateName(cate.getName());
                }
            });
        }

        vo.setStoreAGoodsVos(storeAGoodsVos);


        return ResponseResult.okResult(vo);
    }

    /**
     * @param userInfo
     * @return top.lidee.framework.result.ResponseResult
     * @description 根据当前登录用户下的merchantsId回显数据
     * @author zhangyiheng
     * @date 2024/9/27 10:11
     */
    @Override
    public ResponseResult getByMerchantsIdEcho(UserInfo userInfo) {
        MtUser mtUser = mtUserMapper.selectById(userInfo.getId());

        Integer merchantId = GlobalCheck.checkMerchantId(mtUser.getMerchantId());

        MtMerchant merchant = this.getById(merchantId);

        GetByMerchantsIdEchoVo echoVo = CopyBean.copyBean(merchant, GetByMerchantsIdEchoVo.class);

        return ResponseResult.okResult(echoVo);
    }

    /**
     * @param userInfo
     * @param vo
     * @return top.lidee.framework.result.ResponseResult
     * @description 修改商户
     * @author zhangyiheng
     * @date 2024/9/27 10:28
     */
    @Override
    @Transactional
    public ResponseResult updateByMerchants(UserInfo userInfo, GetByMerchantsIdEchoVo vo) {
        MtUser mtUser = mtUserMapper.selectById(userInfo.getId());

        Integer merchantId = GlobalCheck.checkMerchantId(mtUser.getMerchantId());

        if (!Objects.equals(merchantId, vo.getMerchantId())) {
            return ResponseResult.errorResult(CommonExceptionEnum.NOT_PERMISSION);
        }

        MtMerchant mtMerchant = CopyBean.copyBean(vo, MtMerchant.class);

        this.update(mtMerchant, Wrappers.<MtMerchant>lambdaUpdate()
                .eq(MtMerchant::getId, vo.getMerchantId()));


        return ResponseResult.ok();
    }

    //==============ClientMerchantsController end==============
}
